| The module for an HTTP table rendering. Uses blaze-html to render HTML.

> module Pages.Tables (renderTable) where
> import Text.Blaze.Html5 hiding(map)

| Takes a list of column declarations and
a list of values associated with the table rows,
and produces an HTML-snippet containing the resulting table.

Each column declaration is a tuple `(header, renderer)` with
`header` being a convertible to HTML value to be put into the corresponding column header and
`renderer` being a function mapping from a value associated with the table row
to an HTML-snippet to be displayed at the intersection of the said row and the column.

> renderTable :: (ToHtml h, ToHtml c) =>
>    [(h, a -> c)]  {- ^ Column declarations. -}
>    -> [a] {- ^ Values corresponding to table rows -}
>    -> Html {- ^ The resulting HTML table -}
> renderTable columns items
>     = table $ do
>         headerRow columns
>         mapM_ (bodyRow columns) items

| Returns the header of the table, given the column declarations.

> headerRow :: ToHtml h => [(h, a-> c)] -> Html
> headerRow columns = row (map headerCell columns)

| Returns the function to render the body row, given the column declarations.

> bodyRow :: ToHtml c => [(h, a-> c)] -> a -> Html
> bodyRow columns = let cellRenderers = map bodyCell columns
>                   in row . (sequence cellRenderers)


 (`map` cellRenderers) . flip ($)

| Produces a `<tr/>` HTML element enclosing the given list of `cells`

> row :: [Html] -> Html
> row cells = tr (sequence_ cells)

| Takes a column declaration and produces a `<th/>` HTML element
enclosing its header snippet.

> headerCell :: ToHtml h => (h, a-> c) -> Html
> headerCell (header,_) = th (toHtml header)

| Produces a `<td/>` HTML element enclosing the
result of the given column renderer applied to the given item.

> bodyCell :: ToHtml c => (h, a-> c) -> a -> Html
> bodyCell (_,renderer) item = (td . toHtml . renderer) item
